Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ


Displaying Rendered β€’ View raw β€’ Download

docs/en/developer/testing.md ba63f5911a128c8a9bd2a8cdb567a76f09df7e01 (ba63f591) Text, 4.71 KB

title: Testing
parent: Developer Guide
nav_order: 7
last_updated: 2026-06-11
aliases:
β€’ tests
β€’ unit-tests
β€’ screenshot-tests

Testing

Testing strategy and practices for the Meshtastic KMP project.

Test Categories

KMP Unit Tests (T383838commonTest)

Shared tests that run on all platforms:

T282828
./gradlew allTests

β€’ Business logic tests
β€’ Data model validation
β€’ Search/ranking algorithm tests
β€’ Route serialization tests

Android Host Tests

Android-specific tests that run on JVM:

T282828
./gradlew Tffa657test


β€’ ViewModel tests
β€’ Repository tests with Room fakes
β€’ Android-specific integration tests

Compose UI Tests

Compose Multiplatform UI test framework:

T282828
Tf0883e@Test
Tff7b72fun Td2a8ffmyScreenTestTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runComposeUiTest Tb4b4b4{
Te6edf3setContent Tb4b4b4{ Te6edf3MyScreenTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3onNodeWithTextTb4b4b4(Ta5d6ff"Ta5d6ffExpectedTa5d6ff"Tb4b4b4)Tb4b4b4.Te6edf3assertIsDisplayedTb4b4b4(Tb4b4b4)
Tb4b4b4}


Located in T383838commonTest or T383838jvmTest source sets.

Screenshot Tests

Uses Android Gradle Plugin's native (layoutlib) screenshot testing framework, split across two modules:

β€’ T383838:screenshot-tests β€” the visual-regression gate. CI runs T383838validateDebugScreenshotTest on it; reframing one of these baselines is a real diff to review. Holds atomic, dual-purpose components.
β€’ T383838:docs-screenshots β€” generate-only, not validated in CI. Holds doc-framed compositions whose framing is tuned for the docs site, so reframing a doc image never churns the regression gate.

T282828
./gradlew :screenshot-tests:updateDebugScreenshotTest T8b949e# record regression goldens
./gradlew :screenshot-tests:validateDebugScreenshotTest T8b949e# compare against goldens (CI gate)
./gradlew :docs-screenshots:updateDebugScreenshotTest T8b949e# record doc-framed composition images
./gradlew :screenshot-tests:copyDocsScreenshots T8b949e# copy doc images from BOTH modules into docs/assets


Rendering is host-deterministic here (layoutlib): a local T383838update produces references byte-identical to CI, so locally-recorded goldens pass T383838validate. See T383838docs/assets/screenshots/README.md for which module a new screenshot belongs in.

Baseline Profile / Startup Performance

The T383838:baselineprofile module (#5735) generates a Baseline Profile for T383838:androidApp, AOT-compiling the hot startup paths so ART doesn't pay the JIT cost on first launch. It targets the google flavor (the variant most users run).

The Macrobenchmark generator (T383838BaselineProfileGenerator) and the before/after benchmark (T383838StartupBenchmark) live in T383838baselineprofile/src/main/kotlin/org/meshtastic/baselineprofile/. Both run on a device/emulator:

T282828
./gradlew :androidApp:generateGoogleReleaseBaselineProfile T8b949e# Generate the profile (commit the output)
./gradlew :androidApp:benchmarkGoogleReleaseBaselineProfile T8b949e# Quantify the cold-start win


The generated profile is merged into T383838androidApp/src/google/generated/baselineProfiles/ and packaged into release builds via T383838androidx.profileinstaller.

β”‚ ⚠️ Warning: The journey currently covers cold start only (launch β†’ first frame), because CI has
β”‚ no paired radio. Post-connection screens (node list, map, message thread) are not yet
β”‚ AOT-compiled; extend the journey once a fake transport or connected device is wired into the
β”‚ harness.

Test Organization

T282828
feature/my-feature/src/
β”œβ”€β”€ commonTest/kotlin/org/meshtastic/feature/myfeature/
β”‚ β”œβ”€β”€ MyBusinessLogicTest.kt
β”‚ └── MyModelTest.kt
└── jvmTest/kotlin/org/meshtastic/feature/myfeature/
└── MyDesktopSpecificTest.kt

Testing Guidelines

DO

β€’ Write tests in T383838commonTest when possible (runs everywhere)
β€’ Test business logic independently from UI
β€’ Use fakes/stubs instead of mocks where practical
β€’ Test edge cases: empty states, error states, boundary values
β€’ Test deep link routing in T383838DeepLinkRouterTest
β€’ Keep tests fast β€” no network, no disk I/O in unit tests

DON'T

β€’ Don't test framework behavior (Compose internals, Room queries)
β€’ Don't create tests that depend on other feature modules
β€’ Don't use T383838Thread.sleep β€” use coroutine test dispatchers
β€’ Don't rely on test execution order

Running Tests

T282828
T8b949e# All KMP tests
./gradlew allTests

T8b949e# Specific module
./gradlew :feature:docs:allTests

T8b949e# Code quality
./gradlew spotlessCheck detekt

T8b949e# Full verification
./gradlew spotlessCheck detekt kmpSmokeCompile Tffa657test allTests


CI Integration

Tests run automatically on:
β€’ Pull request creation/update
β€’ Push to T383838main
β€’ Pre-release validation

CI runs on GitHub-hosted Ubuntu 24.04 runners (most jobs use the T383838ubuntu-24.04-arm ARM runners, a few use T383838ubuntu-24.04) with JDK 25 and Gradle caching.


Served by rngit 1.5.0 - Generated in 0.04s